package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.cache.redis.RedisHelper;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.common.vo.common.CommonVO;
import com.bifang.module.base.common.vo.dict.DictAreaVO;
import com.bifang.module.base.common.vo.dict.SelectVO;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.bifang.module.base.core.integration.DictIntegration;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.vo.common.recruitStudent.EduSyncZjDeleteReq;
import com.jwsoft.manager.common.vo.common.recruitStudent.RecruitStudentSyncRetVO;
import com.jwsoft.manager.common.vo.eduSyncZjDelete.EduSyncZjDeleteKeyVO;
import com.jwsoft.manager.common.vo.eduSyncZjDelete.EduSyncZjDeleteQueryVO;
import com.jwsoft.manager.common.vo.eduSyncZjDelete.EduSyncZjDeleteVO;
import com.jwsoft.manager.core.dao.model.EduSyncZjDelete;
import com.jwsoft.manager.core.dao.service.EduSyncZjDeleteService;
import com.jwsoft.manager.core.integration.EduSyncZjDeleteIntegration;
import com.jwsoft.manager.core.util.EduDesensitizeUtil;
import com.jwsoft.manager.core.util.EduHelper;
import com.jwsoft.manager.core.util.EduSyncZjUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 省招生报名专库同步管理业务实现类
 *
 * @author chenzh
 * @since 2023-07-25
 */
@ApiService(funcCode = "eduSyncZj", title = "省招生报名专库同步管理")
@Slf4j
public class EduSyncZjDeleteIntegrationImpl implements EduSyncZjDeleteIntegration {

    @Autowired
    public EduSyncZjDeleteService eduSyncZjDeleteService;
    @Autowired
    private EduHelper eduHelper;
    @Autowired
    private EduSyncZjUtil eduSyncZjUtil;
    @Autowired
    private CommonIntegration commonIntegration;
    @Autowired
    private RedisHelper redisHelper;
    @Autowired
    private DictIntegration dictIntegration;

    @Override
    @OpApi(funcCode = "eduSyncZj0019", title = "省招生报名专库同步管理-删除同步数据分页查询", funcType = FuncTypeEnum.query)
    public PageInfo<EduSyncZjDeleteVO> getList(EduSyncZjDeleteQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        if (vo.getTheYear() == null) {
            vo.setTheYear(eduHelper.thisYear());
        }
        Boolean desensitizeFlag = vo.getDesensitizeFlag();
        if (desensitizeFlag == null){
            desensitizeFlag = true;
        }
        List<String> areaCodeList = new ArrayList<>();
        if (CollectionUtils.isEmpty(areaCodeList)){
            if (ObjectUtils.isEmpty(vo.getApplyCountyCode())){
                List<SelectVO> selectVOList = dictIntegration.getDistrictByOrg(new DictAreaVO());
                areaCodeList = selectVOList.stream()
                        .map(SelectVO::getDictKey)
                        .collect(Collectors.toList());
                String sessionAreaCode = SessionUtil.getAreaCode();
                if (!areaCodeList.contains(sessionAreaCode)) {
                    areaCodeList.add(sessionAreaCode);
                }
            }
        }
        QueryWrapper<EduSyncZjDelete> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(StringUtils.isNotBlank(vo.getIdNumber()), EduSyncZjDelete::getIdNumber, vo.getIdNumber())
                .eq(StringUtils.isNotBlank(vo.getIdType()), EduSyncZjDelete::getIdType, vo.getIdType())
                .eq(StringUtils.isNotBlank(vo.getName()), EduSyncZjDelete::getName, vo.getName())
                .eq(vo.getTheYear() != null, EduSyncZjDelete::getTheYear, vo.getTheYear())
                .eq(StringUtils.isNotBlank(vo.getStage()), EduSyncZjDelete::getStage, vo.getStage())
                .eq(StringUtils.isNotBlank(vo.getSyncStatus()), EduSyncZjDelete::getSyncStatus, vo.getSyncStatus())
                .eq(StringUtils.isNotBlank(vo.getDeleteType()), EduSyncZjDelete::getDeleteType, vo.getDeleteType())
                .eq(vo.getDeleteId() != null, EduSyncZjDelete::getDeleteId, vo.getDeleteId());
        if (!CollectionUtils.isEmpty(areaCodeList)){
            queryWrapper.lambda().in(EduSyncZjDelete::getApplyCountyCode, areaCodeList);
        }else{
            queryWrapper.lambda().eq(EduSyncZjDelete::getApplyCountyCode, vo.getApplyCountyCode());
        }
        queryWrapper.lambda().orderByDesc(EduSyncZjDelete::getUpdateTime,EduSyncZjDelete::getCreateTime)
                .orderByAsc(EduSyncZjDelete::getName,EduSyncZjDelete::getDeleteType);
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduSyncZjDelete> list = eduSyncZjDeleteService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduSyncZjDelete> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduSyncZjDeleteVO> resultList = Convert.toList(EduSyncZjDeleteVO.class, pageInfo.getList());
        // 转义数据字典值
        // dictHelper.valueToName(resultList, Arrays.asList(DemoDictEnum.values()));
        if (desensitizeFlag) {
            for (EduSyncZjDeleteVO syncVO : resultList) {
                syncVO.setName(EduDesensitizeUtil.desensitizeFullName(syncVO.getName()));
                syncVO.setIdNumber(EduDesensitizeUtil.desensitizeIdcard(syncVO.getIdNumber()));
            }
        }
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0018", title = "省招生报名专库同步管理-删除同步数据根据主键查询详情", funcType = FuncTypeEnum.query)
    public EduSyncZjDeleteVO getById(EduSyncZjDeleteKeyVO vo) {
        EduSyncZjDelete entity = eduSyncZjDeleteService.getById(vo.getZjDeleteId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduSyncZjDeleteVO result = Convert.convert(EduSyncZjDeleteVO.class, entity);
        return result;
    }


    @Override
    @OpApi(funcCode = "eduSyncZj0019", title = "省招生报名专库同步管理-删除同步数据新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduSyncZj0019",
            operationName = "省招生报名专库同步管理-删除同步数据新增",
            dataType = "zjDeleteId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSyncZjDeleteVO add(EduSyncZjDeleteVO vo) {

        //保存数据
        EduSyncZjDelete entity = Convert.convert(EduSyncZjDelete.class, vo);
        eduSyncZjDeleteService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setZjDeleteId(entity.getZjDeleteId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0020", title = "省招生报名专库同步管理-删除同步数据修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "eduSyncZj0020",
            operationName = "省招生报名专库同步管理-删除同步数据修改",
            dataType = "zjDeleteId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSyncZjDeleteVO edit(EduSyncZjDeleteVO vo) {
        if (ObjectUtils.isEmpty(vo.getZjDeleteId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduSyncZjDelete oldEntity = eduSyncZjDeleteService.getById(vo.getZjDeleteId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }

        //保存数据
        EduSyncZjDelete entity = Convert.convert(EduSyncZjDelete.class, vo);
        eduSyncZjDeleteService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0021", title = "省招生报名专库同步管理-删除同步数据根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "eduSyncZj0021",
            operationName = "省招生报名专库同步管理-删除同步数据删除",
            dataType = "zjDeleteId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduSyncZjDeleteKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getZjDeleteId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduSyncZjDelete entity = eduSyncZjDeleteService.getById(vo.getZjDeleteId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduSyncZjDeleteService.removeById(vo.getZjDeleteId());
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0025", title = "省招生报名专库同步管理-删除信息同步", funcType = FuncTypeEnum.other)
    @Transactional
    public RecruitStudentSyncRetVO sync(EduSyncZjDeleteKeyVO vo) {
        if (vo.getZjDeleteId() == null) {
            throw new AppException("需要发送的删除id不能为空!");
        }
        EduSyncZjDelete entity = eduSyncZjDeleteService.getById(vo.getZjDeleteId());
        if (entity == null) {
            throw new AppException("需要发送的删除信息不存在!");
        }
        if ("1".equalsIgnoreCase(entity.getSyncStatus())) {
            throw new AppException("已发送成功不能重复发送!");
        }
        //获取appKey
        CommonVO urlVO = new CommonVO();
        urlVO.setParamKey("edu_zj_sync_delete_url");
        String url = commonIntegration.getValueByKey(urlVO);
        if (StringUtils.isBlank(url)) {
            throw new AppException("请先在系统中配置配置省库删除数据地址edu_zj_sync_delete_url");
        }
        EduSyncZjDeleteReq req = Convert.convert(EduSyncZjDeleteReq.class, entity);
        if("330704".equalsIgnoreCase(req.getApplyCountyCode())){
            //金华开发区按婺城区去处理
            req.setApplyCountyCode("330702");
        }
        RecruitStudentSyncRetVO retVO = eduSyncZjUtil.send(url, JSON.toJSONString(req),entity.getApplyCountyCode());
        if ("200".equalsIgnoreCase(retVO.getCode())) {
            entity.setSyncStatus("1");
            entity.setSyncMsg("调用成功");
            //调用成功，根据类型和deleteId删除省同步表的数据
            eduSyncZjDeleteService.deleteByTypeAndId(entity.getDeleteType(),entity.getDeleteId());
        } else {
            entity.setSyncStatus("2");
            if (StringUtils.isNotBlank(retVO.getMsg())) {
                if (retVO.getMsg().length() < 300) {
                    entity.setSyncMsg(retVO.getMsg());
                } else {
                    entity.setSyncMsg(retVO.getMsg().substring(0, 300));
                }
            } else {
                entity.setSyncMsg(retVO.getMsg());
            }

        }
        entity.setSyncTime(new Date());
        eduSyncZjDeleteService.updateById(entity);
        return retVO;
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0032", title = "省招生报名专库同步管理-删除信息批量同步", funcType = FuncTypeEnum.other)
    @Async("commonTaskExecutor")
    public void batchSync(EduSyncZjDeleteQueryVO vo) {
        String redisKey = "edu:zjSync:send:delete";
        if (redisHelper.hasKey(redisKey)) {
            throw new AppException("正在执行中");
        }
        redisHelper.set(redisKey, true, 3600);
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        vo.setTheYear(eduHelper.thisYear());
        if (StringUtils.isBlank(vo.getApplyCountyCode())) {
            vo.setApplyCountyCode(SessionUtil.getAreaCode());
        }
        if (StringUtils.isBlank(vo.getApplyCountyCode())) {
            vo.setApplyCountyCode(eduHelper.thisAreaCode());
        }
        if (StringUtils.isBlank(vo.getSyncStatus())) {
            vo.setSyncStatus("0");
        }
        try {
            batchSyncDo(vo);
        } catch (Exception e) {
            redisHelper.del(redisKey);
            e.printStackTrace();
        }

    }

    public void batchSyncDo(EduSyncZjDeleteQueryVO vo) {
        String redisKey = "edu:zjSync:send:delete";
        QueryWrapper<EduSyncZjDelete> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(StringUtils.isNotBlank(vo.getApplyCountyCode()), EduSyncZjDelete::getApplyCountyCode, vo.getApplyCountyCode())
                .eq(StringUtils.isNotBlank(vo.getIdNumber()), EduSyncZjDelete::getIdNumber, vo.getIdNumber())
                .eq(StringUtils.isNotBlank(vo.getIdType()), EduSyncZjDelete::getIdType, vo.getIdType())
                .eq(StringUtils.isNotBlank(vo.getName()), EduSyncZjDelete::getName, vo.getName())
                .eq(vo.getTheYear() != null, EduSyncZjDelete::getTheYear, vo.getTheYear())
                .eq(StringUtils.isNotBlank(vo.getStage()), EduSyncZjDelete::getStage, vo.getStage())
                .eq(StringUtils.isNotBlank(vo.getSyncStatus()), EduSyncZjDelete::getSyncStatus, vo.getSyncStatus())
                .eq(StringUtils.isNotBlank(vo.getDeleteType()), EduSyncZjDelete::getDeleteType, vo.getDeleteType())
                .eq(vo.getDeleteId() != null, EduSyncZjDelete::getDeleteId, vo.getDeleteId()).orderByAsc(EduSyncZjDelete::getCreateTime);
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduSyncZjDelete> list = eduSyncZjDeleteService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            redisHelper.del(redisKey);
            return;
        }
        // 不为空则获取分页结果
        PageInfo<EduSyncZjDelete> pageInfo = new PageInfo<>(list);
        for (EduSyncZjDelete eduSyncZjDelete : pageInfo.getList()) {
            EduSyncZjDeleteKeyVO keyVO = new EduSyncZjDeleteKeyVO();
            keyVO.setZjDeleteId(eduSyncZjDelete.getZjDeleteId());
            try {
                this.sync(keyVO);
            } catch (Exception e) {
                log.error("同步省库异常"+e.getMessage(),e);
            }
        }

        redisHelper.del(redisKey);

    }
}